package com.munhrasoft.dinamica.business.logic;

import java.text.DecimalFormat;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.munhrasoft.dinamica.business.entities.Custo;
import com.munhrasoft.dinamica.business.entities.Imovel;
import com.munhrasoft.dinamica.business.entities.ProcessoChkHeader;

@Stateless
public class CustoEJB {

    @EJB
    private CustoCNotasEJB custoCNotasEJB;
    @EJB
    private CustoCRIEJB    custoCRIEJB;

    @PersistenceContext(unitName = "dinamicaPU")
    private EntityManager  em;

    public void calculaCustoProcesso(Custo custo, ProcessoChkHeader pchkHeader,
            boolean primeiroimovel, Imovel imovel) {

        double custo_ibti = 0;
        double custo_cnota = 0;
        double custo_desp = 0;

        custo_ibti = custo.getParamibti() * imovel.getValcompvendatotal();
        custo_cnota = custoCNotasEJB.custoPorValor(imovel.getValcompvendatotal());
        custo_desp = custo.getParamdesp();

        custo.setCusoibti(custo_ibti);
        custo.setCustocnotas(custo_cnota);
        custo.setCustodesp(custo_desp);

        calculaCustoCaixa(custo, pchkHeader, primeiroimovel, imovel);
        calculaCustoCRI(custo, pchkHeader, imovel, primeiroimovel);

        custo.setCustototal(custo.getCusoibti() + custo.getCustocaixa() + custo.getCustocnotas()
                + custo.getCustocri() + custo.getCustodesp());

    }

    private void calculaCustoCRI(Custo custo, ProcessoChkHeader chkHeader, Imovel imovel,
            boolean primeiroimovel) {

        if (chkHeader.getModalidade1().equals("CCFGTS")) {
            calculaCustoCRICCFGTS(custo, imovel, primeiroimovel);
        } else if (chkHeader.getModalidade1().equals("CCSBPE")) {
            calculaCustoCRICCSBPE(custo, imovel, primeiroimovel);
        }

    }

    /**
     * Calcula custo para o cartorio de registro de imoveis
     * 
     * @param custo
     * @param imovel
     */

    private void calculaCustoCRICCFGTS(Custo custo, Imovel imovel, boolean primeiroimovel) {

        double custo_cri = 0.0;
        double cri_garagem = 0.0;
        double cri_apt = 0.0;
        double val_alienacao = 0.0;

        if (primeiroimovel) {
            // se for primeiro imovel
            if (imovel.isGaragem()) {
                // com garagem

                cri_garagem = custoCRIEJB.custoPorValor(imovel.getValorcompvendagaragem());
                cri_apt = custoCRIEJB.custoPorValor(imovel.getValcompvendaapto());
                val_alienacao = custoCRIEJB.custoPorValor(imovel.getValorfinanc() / 2);

                cri_garagem = ((cri_garagem + val_alienacao) * 0.5) + 2
                        * custo.getParamvmatricula();
                cri_apt = ((cri_apt + val_alienacao) * 0.5) + 2 * custo.getParamvmatricula();

                custo_cri = cri_garagem + cri_apt;

            } else {
                // sem garagem

                custo_cri = (custoCRIEJB.custoPorValor(imovel.getValcompvendatotal()) + custoCRIEJB
                        .custoPorValor(imovel.getValorfinanc()))
                        * 0.5
                        + 2
                        * custo.getParamvmatricula();
            }

        } else {
            // se nao for primeiro imovel
            if (imovel.isGaragem()) {
                // com garagem

                cri_garagem = custoCRIEJB.custoPorValor(imovel.getValorcompvendagaragem());
                cri_apt = custoCRIEJB.custoPorValor(imovel.getValcompvendaapto());
                val_alienacao = custoCRIEJB.custoPorValor(imovel.getValorfinanc() / 2);

                cri_garagem = (cri_garagem + val_alienacao) + 2 * custo.getParamvmatricula();

                cri_apt = (cri_apt + val_alienacao) + 2 * custo.getParamvmatricula();

                custo_cri = cri_garagem + cri_apt;

            } else {
                // sem garagem, como nao tem garagem pega o valor total passar o
                // valor d apt para o
                // valor total do imovel sempre fazer as contas com o valor
                // total do imovel

                cri_apt = custoCRIEJB.custoPorValor(imovel.getValcompvendatotal());
                val_alienacao = custoCRIEJB.custoPorValor(imovel.getValorfinanc());
                custo_cri = cri_apt + val_alienacao + 2 * custo.getParamvmatricula();

            }

        }

        custo.setCustocri(custo_cri);

    }

    private void calculaCustoCRICCSBPE(Custo custo, Imovel imovel, boolean primeiroimovel) {

        double custo_cri = 0.0;
        double cri_garagem = 0.0;
        double cri_apt = 0.0;
        double taxapart1 = 0.0;
        double taxapart2 = 0.0;

        double taxagaragem1 = 0.0;
        double taxagaragem2 = 0.0;

        // double somaParts = 0.0;
        double tarifa_cv_apto = 0.0;
        double tarifa_cv_garagem = 0.0;
        double val_alienacao = 0.0;

        if (primeiroimovel) {
            // se for primeiro imovel
            if (imovel.isGaragem()) {
                // com garagem

                cri_apt = custoCRIEJB.custoPorValor(imovel.getValcompvendaapto());

                taxapart1 = cri_apt
                        * (trunca4Casas(imovel.getValorfinanc() / imovel.getValcompvendatotal()));

                taxapart2 = cri_apt - taxapart1;
                taxapart1 = taxapart1 * 0.5;
                tarifa_cv_apto = taxapart1 + taxapart2;

                val_alienacao = custoCRIEJB.custoPorValor(imovel.getValorfinanc() / 2);

                val_alienacao = val_alienacao / 2;

                cri_apt = tarifa_cv_apto + val_alienacao + 2 * custo.getParamvmatricula();

                cri_garagem = custoCRIEJB.custoPorValor(imovel.getValorcompvendagaragem());

                taxagaragem1 = cri_garagem
                        * (trunca4Casas(imovel.getValorfinanc() / imovel.getValcompvendatotal()));
                taxagaragem2 = cri_garagem - taxagaragem1;
                taxagaragem1 = taxagaragem1 * 0.5;

                tarifa_cv_garagem = taxagaragem2 + taxagaragem1;

                cri_garagem = tarifa_cv_garagem + val_alienacao + 2 * custo.getParamvmatricula();

                custo_cri = cri_garagem + cri_apt;

            } else {
                // sem garagem

                cri_apt = custoCRIEJB.custoPorValor(imovel.getValcompvendatotal());

                taxapart1 = cri_apt
                        * (trunca4Casas(imovel.getValorfinanc() / imovel.getValcompvendatotal()));
                taxapart2 = cri_apt - taxapart1;

                taxapart1 = taxapart1 * 0.5;

                tarifa_cv_apto = taxapart1 + taxapart2;

                val_alienacao = custoCRIEJB.custoPorValor(imovel.getValorfinanc());
                val_alienacao = val_alienacao * 0.5;

                custo_cri = tarifa_cv_apto + val_alienacao + 2 * custo.getParamvmatricula();

            }

        } else {
            // se nao for primeiro imovel
            if (imovel.isGaragem()) {
                // TODO com garagem

                tarifa_cv_apto = custoCRIEJB.custoPorValor(imovel.getValcompvendaapto());

                val_alienacao = custoCRIEJB.custoPorValor(imovel.getValorfinanc() / 2);

                cri_apt = tarifa_cv_apto + val_alienacao + 2 * custo.getParamvmatricula();

                tarifa_cv_garagem = custoCRIEJB.custoPorValor(imovel.getValorcompvendagaragem());

                cri_garagem = tarifa_cv_garagem + val_alienacao + 2 * custo.getParamvmatricula();

                custo_cri = cri_garagem + cri_apt;

            } else {
                // sem garagem

                tarifa_cv_apto = custoCRIEJB.custoPorValor(imovel.getValcompvendatotal());

                val_alienacao = custoCRIEJB.custoPorValor(imovel.getValorfinanc());

                cri_apt = tarifa_cv_apto + val_alienacao + 2 * custo.getParamvmatricula();

                custo_cri = cri_apt;

            }

        }

        custo.setCustocri(custo_cri);

    }

    /**
     * Calcula custo para o cartorio de notas
     * 
     * @param custo
     * @param chkHeader
     * @param primeiroimovel
     */

    private void calculaCustoCaixa(Custo custo, ProcessoChkHeader chkHeader,
            boolean primeiroimovel, Imovel imovel) {

        if (chkHeader.getModalidade1().equals("CCFGTS")) {
            calculaCustoCCFGTS(custo, primeiroimovel, imovel);
        } else if (chkHeader.getModalidade1().equals("CCSBPE")) {
            calculaCustoCCSBPE(custo, primeiroimovel, imovel);
        }

    }

    private void calculaCustoCCFGTS(Custo custo, boolean primeiroimovel, Imovel imovel) {
        // TODO nao precisa de primeiro imovel
        double custo_caixa = 0;
        custo_caixa = custo.getParamtxccfgts() * imovel.getValorfinanc()
                + custo.getParampesqcadastral() + custo.getParampremioseguro();
        custo.setCustocaixa(custo_caixa);
    }

    private void calculaCustoCCSBPE(Custo custo, boolean primeiroimovel, Imovel imovel) {

        double custo_caixa = 0;

        custo_caixa = custo.getParamtxccsbte() + custo.getParampesqcadastral()
                + custo.getParampremioseguro();
        custo.setCustocaixa(custo_caixa);

    }

    /**
     * Trunca de um double para duas casas decimais
     * 
     * @param valor
     * @return
     */
    private double trunca4Casas(double valor) {
        // TODO arrumar para 4 casas
        double resultado = 0.0;
        DecimalFormat df = new DecimalFormat("#.####");
        resultado = new Double(df.format(valor));
        return resultado;

    }

}
